package com.smoed.common.utilities;

import java.io.IOException;
import java.net.*;
import java.util.Random;

public final class NetworkUtils {

    private NetworkUtils() {
    }

    public static String getMacAddress() {
        final StringBuffer macAddress = new StringBuffer();
        try {
            final byte[] mac = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()).getHardwareAddress();

            for (int i = 0; i < mac.length; i++) {
                macAddress.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        return macAddress.toString();
    }

    public static String getLocalHostName() {
        String hostName = "";
        try {
            hostName = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return hostName;
    }

    private final static String[] internetConnectionTestUrls = {
        "http://www.google.com/",
        "http://www.yahoo.com/",
        "http://www.msn.com/",
        "http://www.bing.com/",
        "http://www.aol.com/",
        "http://www.ask.com/"
    };
    private final static Random randomTestUrlIndex = new Random();
    private final static int indexRange = internetConnectionTestUrls.length;

    private static String getRandomTestUrl() {
        return internetConnectionTestUrls[randomTestUrlIndex.nextInt(indexRange)];
    }
    private final static int NUM_URLS_TO_TEST_BEFORE_DETERMINING_NO_INTERNET_CONNECTION = 2;

    public static boolean isInternetReachable() {
        for (int i = 0; i < NUM_URLS_TO_TEST_BEFORE_DETERMINING_NO_INTERNET_CONNECTION; i++) {
            if (isHttpUrlReachable(getRandomTestUrl())) return true;
        }
        return false;
    }

    private static boolean isHttpUrlReachable(String urlString) {
        HttpURLConnection testHttpUrlConnection = null;
        try {
            final URL url = new URL(urlString);
            testHttpUrlConnection = (HttpURLConnection)url.openConnection();
            testHttpUrlConnection.getContent();
        } catch (UnknownHostException e) {
            return false;
        } catch (IOException e) {
            return false;
        } finally {
            if (testHttpUrlConnection != null) {
                testHttpUrlConnection.disconnect();
            }
        }
        return true;
    }

    private static final int MAX_RE_CONNECT_WAIT_TIME = 300000; // 5 minutes

    public static double getReConnectWaitTime(int connectionAttemptNum) {
        double waitTime = 1000;
        if (connectionAttemptNum < 10) {
            waitTime *= connectionAttemptNum;
        } else if (connectionAttemptNum > 12) {
            waitTime = MAX_RE_CONNECT_WAIT_TIME;
        } else {
            waitTime = Math.exp(connectionAttemptNum);
        }

        return waitTime;
    }
}
